package cqrtplm.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hustcad.plm.pdm.basedrule.dto.TyplmBaseRuleBoundedObjDTO;
import com.hustcad.plm.pdm.basedrule.service.TyplmBasedRuleService;
import com.hustcad.plm.pdm.code.model.dto.codemanagement.TyplmSegmentCodeConditionDTO;
import com.hustcad.plm.pdm.ec.module.dto.TyplmChangeIssueDTO;
import com.hustcad.plm.pdm.ec.module.dto.TyplmChangeIssueDetailDTO;
import com.hustcad.plm.pdm.ec.service.TyplmChangeIssueService;
import com.hustcad.plm.pdm.form.model.vo.FormTemplateVO;
import com.hustcad.plm.pdm.form.service.TyplmFormTemplateService;
import com.hustcad.plm.pdm.type.service.TyplmTypeService;
import com.hustcad.plm.pdm.user.service.TyplmUserService;
import com.hustcad.plm.rpm.model.dto.issue.CreatIssueLinkDTO;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.entity.org.UserDO;
import cqrtplm.common.CommonService;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.constant.RTPlmConstant;
import cqrtplm.dto.ImportProjectRiskDTO;
import cqrtplm.mapper.ProjectMapper;
import cqrtplm.service.ProjectRiskFormService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.ty.basic.utils.excel.converter.ExcelToList.getWorkbook;

@Service
@Slf4j
public class ProjectRiskFormServiceImpl implements ProjectRiskFormService {
    @Resource
    private TyplmTypeService typlmTypeService;
    @Resource
    private TyplmChangeIssueService typlmChangeIssueService;
    @Resource
    private TyplmBasedRuleService typlmBasedRuleService;
    @Resource
    private TyplmFormTemplateService typlmFormTemplateService;
    @Resource
    private CommonService commonService;
    @Value("${ipd.base.url:http://127.0.0.1:9588}")
    private String ipdUrl;
    @Resource
    private ProjectMapper projectMapper;

    @Override
    public List<ImportProjectRiskDTO> getRiskFileData(MultipartFile file) throws Exception{
        return readDataFromExcel(file);
    }

    private static String readCellValue(Row row, int i, DataFormatter dataFormatter, SimpleDateFormat dateFormat) {
        Cell cell = row.getCell(i);
        String cellValue;
        if (cell.getCellType() == CellType.NUMERIC && DateUtil.isCellDateFormatted(cell)) {
            Date date = cell.getDateCellValue();
            cellValue = dateFormat.format(date);
        } else {
            cellValue = dataFormatter.formatCellValue(cell);
        }
        return cellValue;
    }

    private List<ImportProjectRiskDTO> readDataFromExcel(MultipartFile file) {
        List<ImportProjectRiskDTO> projectDataList = new ArrayList<>();
        try {
            Workbook workbook = getWorkbook(file);
            Sheet sheet = workbook.getSheetAt(0);

            DataFormatter dataFormatter = new DataFormatter();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            // 获取第二行数据作为全局属性
            Row row2 = sheet.getRow(1);
            String projectNumber = readCellValue(row2, 1, dataFormatter, dateFormat);
            String projectName = readCellValue(row2, 3, dataFormatter, dateFormat);
            String projectLeader = readCellValue(row2, 5, dataFormatter, dateFormat);
            // 从第四行开始遍历数据
            for (int i = 3; i < sheet.getPhysicalNumberOfRows(); i++) {
                Row row = sheet.getRow(i);
                String serialNumber = readCellValue(row, 0, dataFormatter, dateFormat);
                String riskEvent = readCellValue(row, 1, dataFormatter, dateFormat);
                String type = readCellValue(row, 2, dataFormatter, dateFormat);
                String impact = readCellValue(row, 3, dataFormatter, dateFormat);
                String occurrenceTime = readCellValue(row, 4, dataFormatter, dateFormat);
                String occurrenceProbability = readCellValue(row, 5, dataFormatter, dateFormat);
                String occurrenceStage = readCellValue(row, 6, dataFormatter, dateFormat);
                String occurrenceSign = readCellValue(row, 7, dataFormatter, dateFormat);
                String responseMeasures = readCellValue(row, 8, dataFormatter, dateFormat);
                String personInCharge = readCellValue(row, 9, dataFormatter, dateFormat);
                String plannedCompletionTime = readCellValue(row, 10, dataFormatter, dateFormat);
                String remarks = readCellValue(row, 11, dataFormatter, dateFormat);
                ImportProjectRiskDTO projectData = new ImportProjectRiskDTO();
                projectData.setProjectNumber(projectNumber);
                projectData.setProjectName(projectName);
                projectData.setProjectLeader(projectLeader);
                projectData.setSerialNumber(serialNumber);
                projectData.setRiskEvent(riskEvent);
                projectData.setType(type);
                projectData.setImpact(impact);
                projectData.setOccurrenceTime(occurrenceTime);
                projectData.setOccurrenceProbability(occurrenceProbability);
                projectData.setOccurrenceStage(occurrenceStage);
                projectData.setOccurrenceSign(occurrenceSign);
                projectData.setResponseMeasures(responseMeasures);
                projectData.setPersonInCharge(personInCharge);
                projectData.setPlannedCompletionTime(plannedCompletionTime);
                projectData.setRemarks(remarks);
                projectDataList.add(projectData);
            }
            workbook.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return projectDataList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchCreateRiskFileData(List<ImportProjectRiskDTO> data) throws Exception{
        String finalUrl = ipdUrl+"/api/v1/projectIssue/batchCreatChangeIssueLink";
        String projectOid = data.get(0).getOid();
        String projectNumber = projectMapper.selectProjectNumberByOid(projectOid);
        String excelProjectNumberData = data.get(0).getProjectNumber();
        if(!projectNumber.equals(excelProjectNumberData)){
            throw RTErrorCodeEnum.STATUS_INFO_CONTENT_IS_NULL.getException("项目编号不一致,无法导入");
        }
        BigInteger riskOid = typlmTypeService.getTypeOidByName("Risk");
        TyplmBaseRuleBoundedObjDTO info = this.typlmBasedRuleService.getBaseRuleBoundedObjInfo(
                riskOid, new BigInteger(projectOid), TableTypeConstrant.TY_PROJECT_TYPE);
        TyplmSegmentCodeConditionDTO param = new TyplmSegmentCodeConditionDTO();
        param.setOtype(TableTypeConstrant.TY_CHANGEISSUE_OTYPE);
        param.setRuleInfo(new IdentifierEntity(info.getSegmentCodeOid(), info.getSegmentCodeOtype()));
        FormTemplateVO formTemplateData = this.typlmFormTemplateService.getFormTemplateByType(riskOid);
        JSONObject templatedata = formTemplateData.getTemplatedata();
        for (ImportProjectRiskDTO dto : data) {
            TyplmChangeIssueDTO changeRiskDTO = new TyplmChangeIssueDTO();
            //            TyplmSegmentCodeRuleVO codeData = this.typlmSegmentCodeService.getSegmentFormData(param);
            changeRiskDTO.setName("风险");
            String projectNo = dto.getProjectNumber();
            changeRiskDTO.setContainerotype(TableTypeConstrant.TY_PROJECT_TYPE);
            changeRiskDTO.setContaineroid(new BigInteger(projectOid));
            changeRiskDTO.setTypeoid(riskOid);
            changeRiskDTO.setObjectNumber("risk"+System.currentTimeMillis());
            changeRiskDTO.setFormtemplateoid(info.getFormTemplateOid());
            changeRiskDTO.setFormtemplateotype(info.getFormTemplateOtype());

            changeRiskDTO.setFormData(buildFormData(dto,templatedata));
            changeRiskDTO.setIssuepriority(RTPlmConstant.NORMAL);
            List<TyplmChangeIssueDetailDTO> changeRisk = typlmChangeIssueService.createChangeIssueAndEcLink(changeRiskDTO);

            CreatIssueLinkDTO creatIssueLink = new CreatIssueLinkDTO();
            creatIssueLink.setLocalRepositoryUid("javaPDM");
            creatIssueLink.setProjectOid(projectOid);
            creatIssueLink.setProjectOtype(TableTypeConstrant.TY_PROJECT_TYPE);
            List<JSONObject> objectList = JSON.parseArray(JSON.toJSONString(changeRisk), JSONObject.class);
            creatIssueLink.setObjectList(objectList);
            commonService.sendPostRequestToIPD(finalUrl, JSON.toJSONString(creatIssueLink));
        }
    }

    private String buildFormData(ImportProjectRiskDTO dto, JSONObject formJson) {
        formJson.put("ProjectNumber", dto.getProjectNumber());
        formJson.put("ProjectName", dto.getProjectName());
        formJson.put("ProjectLeader", dealFromDataUser(dto.getProjectLeader()));
        formJson.put("RiskEvent", dto.getRiskEvent());
        formJson.put("Type", dto.getType());
        formJson.put("Influence", dto.getImpact());
        formJson.put("OccurrenceProcess", dto.getOccurrenceStage());
        formJson.put("TimeOccurrence", dto.getOccurrenceTime());
        formJson.put("ProbabilityOccurrence", dto.getOccurrenceProbability());
        formJson.put("SignsOccurrence", dto.getOccurrenceSign());
        formJson.put("RiskResponseMeasures",  dto.getResponseMeasures());
        formJson.put("PersonCharge", dealFromDataUser(dto.getPersonInCharge()));
        formJson.put("PlannedCompletionTime", dto.getPlannedCompletionTime());
        formJson.put("Remarks", dto.getRemarks());
        return formJson.toJSONString();
    }

    @Resource
    private TyplmUserService typlmUserService;
    private JSONArray dealFromDataUser(String projectLeader) {
        JSONArray userArray = new JSONArray();
        String[] usernames = projectLeader.split(",");

        for (String username : usernames) {
            List<UserDO> userDOS = typlmUserService.fuzzyQueryUserForEnabled(username);
            if(CollUtil.isEmpty(userDOS)){
                continue;
            }
            UserDO userDO = userDOS.get(0);
            JSONObject user = new JSONObject();
            user.put("oid", userDO.getOid());
            user.put("otype", userDO.getOtype());
            user.put("fullName", userDO.getFullname());
            user.put("fullNamePinYin", userDO.getFullnamepinyin());
            user.put("namePinYin", userDO.getName());
            user.put("containerOid", userDO.getContaineroid());
            user.put("containerOtype", userDO.getContainerotype());
            user.put("name", userDO.getName());
            user.put("createStamp", userDO.getCreatestamp());
            user.put("rowValue", userDO.getOid());
            userArray.add(user);
        }

        return userArray;
    }
}
